using System;
using System.Collections.Generic;
using System.Data;
using System.Globalization;
using System.IO;
using System.Web.UI.WebControls;
using System.Xml;
using DotNetNuke.Common.Utilities;
using DotNetNuke.Entities.Portals;
using DotNetNuke.Entities.Users;
using DotNetNuke.Modules.NBrightEspace.Data;
using Microsoft.ApplicationBlocks.Data;
using NBrightCore.common;
using NBrightCore.render;
using NBrightDNN;

namespace DotNetNuke.Modules.NBrightEspace.Components
{

    /// -----------------------------------------------------------------------------
    /// <summary>
    /// The Controller class for NBrightEspace
    /// </summary>
    /// -----------------------------------------------------------------------------

    //uncomment the interfaces to add the support.
    public class EspaceController : DataCtrlInterface
    {

        public NBrightDNN.NBrightInfo GetByGuidKey(int PortalId, int ModuleId, string EntityTypeCode, string GuidKey, string selUserId = "")
        {
            var l = CBO.FillCollection<NBrightInfo>(DataProvider.Instance().GetList(EntityTypeCode, " and GUIDKey = '" + GuidKey + "' ", "", 1, 1, 1, 1));
            if (l.Count == 0)
            {
                return null;
            }
            if (l.Count > 1)
            {
                for (int i = 1; i < l.Count; i++)
                {
                    // remove invalid DB entries
                    Delete(l[i].ItemID);
                }
            }
            return l[0];
        }

        public override List<NBrightInfo> GetList(int portalId, int moduleId, string typeCode, string sqlSearchFilter = "", string sqlOrderBy = "",
            int returnLimit = 0, int pageNumber = 0, int pageSize = 0, int recordCount = 0, string typeCodeLang = "",
            string lang = "")
        {
            return CBO.FillCollection<NBrightDNN.NBrightInfo>(DataProvider.Instance().GetList(typeCode, sqlSearchFilter, sqlOrderBy, returnLimit, pageNumber, pageSize, recordCount));
        }

        public override int GetListCount(int portalId, int moduleId, string typeCode, string sqlSearchFilter = "", string typeCodeLang = "",
            string lang = "")
        {
            return DataProvider.Instance().GetListCount(typeCode, sqlSearchFilter);
        }

        public override NBrightInfo Get(int itemId, string typeCodeLang = "", string lang = "")
        {
            return CBO.FillObject<NBrightDNN.NBrightInfo>(DataProvider.Instance().Get(itemId));
        }

        public override int Update(NBrightInfo objInfo)
        {
            objInfo.ModifiedDate = DateTime.Now;
            return DataProvider.Instance().Update(objInfo.ItemID, objInfo.TypeCode, objInfo.XMLData, objInfo.GUIDKey, objInfo.ModifiedDate);
        }

        public override void Delete(int itemId)
        {
            DataProvider.Instance().Delete(itemId);
        }

        public override void CleanData()
        {
            throw new NotImplementedException();
        }

        public NBrightDNN.NBrightInfo GetDataWithLang(int PortalId, int ModuleId, string parentItemId, string cultureCode, string entityTypeCodeLang,string UserId = "")
        {
            NBrightInfo rtnObj = null;
            var c = 0;
            var strFilter = " and (([xmlData].value('(genxml/hidden/lang)[1]', 'nvarchar(10)') = '" + cultureCode + "' or [xmlData].value('(genxml/hidden/lang)[1]', 'nvarchar(10)') = ''))";
            if (Utils.IsNumeric(parentItemId))
            {
                strFilter = " and parentitemid = " + parentItemId + strFilter;
            }
            var l = GetList(PortalId, ModuleId, entityTypeCodeLang, strFilter, "", 1);
            if (l != null) c = l.Count;
            if (c == 0)
            {
                // create new object to return.
                rtnObj = new NBrightInfo();
                rtnObj.ItemID = -1;
                rtnObj.ModuleId = ModuleId;
                rtnObj.PortalId = PortalId;
                if (Utils.IsNumeric(parentItemId))
                {
                    rtnObj.ParentItemId = Convert.ToInt32(parentItemId);
                }
            }
            else
            {
                rtnObj = l[0];
            }
            return rtnObj;
        }

        public List<NBrightDNN.NBrightInfo> GetListWithLang(int PortalId, int ModuleId, string typeCode, string strFilters, string strOrderBy, int returnLimit = 0, int pageNumber = 0, int pageSize = 0, int recordCount = 0, string entityTypeCodeLang = "", string selUserId = "", bool debugMode = false)
        {
            var l = GetList(PortalId, ModuleId, typeCode, strFilters, strOrderBy, returnLimit, pageNumber, pageSize, recordCount, entityTypeCodeLang);
            if (!String.IsNullOrEmpty(entityTypeCodeLang))
            {
                foreach (var o in l)
                {
                    var oLang = GetDataWithLang(PortalId, ModuleId, o.ItemID.ToString(""), Utils.GetCurrentCulture(), entityTypeCodeLang);
                    if (oLang.XMLData != null)
                    {
                        o.XMLData = o.XMLData.Replace("</genxml>", ""); // remove closing tag
                        o.XMLData = o.XMLData + "<lang>" + oLang.XMLData + "</lang>"; // Add Langauge xml
                        o.XMLData = o.XMLData + "</genxml>"; // Add back closing tag
                    }
                }
            }
            return l;
        }

        public List<NBrightInfo> GetListWithLang(Repeater rp1, int portalId, int moduleId, string typeCode, int returnLimit = 0, int pageNumber = 0, int pageSize = 0, string entityTypeCodeLang = "", string selUserId = "", bool debugMode = false)
        {
            var strFilters = GenXmlFunctions.GetSqlSearchFilters(rp1);
            var strOrderBy = GenXmlFunctions.GetSqlOrderBy(rp1);
            //Default orderby if not set
            if (String.IsNullOrEmpty(strOrderBy)) strOrderBy = " Order by ModifiedDate DESC ";
            return GetListWithLang(portalId, moduleId, typeCode, strFilters, strOrderBy, returnLimit, pageNumber, pageSize, 0, entityTypeCodeLang, selUserId, debugMode);
        }

        public NBrightInfo GetByType(int PortalId, int ModuleId, string EntityTypeCode, string selUserId = "", string lang = "")
        {
            var strFilter = "";
            if (selUserId != "")
            {
                strFilter += " and UserId = " + selUserId + " ";
            }
            if (lang != "")
            {
                strFilter += " and lang = '" + lang + "' ";
            }

            var l = CBO.FillCollection<NBrightInfo>(DataProvider.Instance().GetList(EntityTypeCode, "", "", 1, 1, 1, 1));
            if (l.Count >= 1)
            {
                return l[0];
            }
            return null;

        }



        #region "Invoice Public Methods"

        public NBrightInfo UpdateInvoice(int itemId, Repeater rpData, Repeater rpArticle, string entityTypeCode,string InvoicePrefix = "FA3")
        {
            // Do any special updates that are required.
            double grandTotal = 0;
            double subTotal = 0;
            double taxTotal = 0;
            double totalDue = 0;
            string alreadyPaid = null;

            //rebuild all articles.
            taxTotal = 0;
            subTotal = 0;

            foreach (RepeaterItem dItem in rpArticle.Items)
            {
                //calculate total
                var articlePrice = GenXmlFunctions.GetField(rpArticle, "txtPrice", dItem.ItemIndex);
                var articleTax = GenXmlFunctions.GetField(rpArticle, "ddlTax", dItem.ItemIndex);
                double articleTotal = 0;
                if (Utils.IsNumeric(articlePrice, Utils.GetCurrentCulture()) & Utils.IsNumeric(articleTax, Utils.GetCurrentCulture()))
                {
                    subTotal += Math.Round(Convert.ToDouble(articlePrice),2);
                    articleTotal = Math.Round(Convert.ToDouble(articlePrice)*((100 + Convert.ToDouble(articleTax))/100), 2);
                    taxTotal += Math.Round(Convert.ToDouble(articleTotal) - Convert.ToDouble(articlePrice),2);
                }
                else
                {
                    articleTotal = 0;
                }
                grandTotal += articleTotal;
                GenXmlFunctions.SetHiddenField(rpArticle, "dblTotalPrice", Convert.ToString(articleTotal), dItem.ItemIndex);

                var objAInfo = new NBrightInfo();
                if (Utils.IsNumeric(GenXmlFunctions.GetHiddenField(rpArticle, "ItemID", dItem.ItemIndex)))
                {
                    objAInfo.ItemID = GenXmlFunctions.GetFieldAsInteger(rpArticle, "ItemID", dItem.ItemIndex);
                }
                else
                {
                    objAInfo.ItemID = -1;
                }
                objAInfo.TypeCode = entityTypeCode + Convert.ToString(itemId);
                objAInfo.XMLData = GenXmlFunctions.GetGenXml(rpArticle, dItem.ItemIndex);
                Update(objAInfo);
            }


            alreadyPaid = GenXmlFunctions.GetField(rpData, "txtAlreadyPaid");
            if (Utils.IsNumeric(alreadyPaid, Utils.GetCurrentCulture()))
            {
                totalDue = grandTotal - Math.Round(Convert.ToDouble(alreadyPaid), 2);
            }
            else
            {
                totalDue = grandTotal;
            }

            GenXmlFunctions.SetHiddenField(rpData, "dteModifiedDate", Convert.ToString(DateTime.Now));
            GenXmlFunctions.SetHiddenField(rpData, "dblGrandTotal", Convert.ToString(grandTotal));
            GenXmlFunctions.SetHiddenField(rpData, "dblSubTotal", Convert.ToString(subTotal));
            GenXmlFunctions.SetHiddenField(rpData, "dblTaxTotal", Convert.ToString(taxTotal));
            GenXmlFunctions.SetHiddenField(rpData, "dblTotalDue", Convert.ToString(totalDue));

            var objInfo = Get(itemId); // get working data
            if (objInfo == null)
            {
                // new item, so create it
                objInfo = new NBrightInfo();
                objInfo.ItemID = itemId;
                objInfo.TypeCode = entityTypeCode;
            }

            objInfo.XMLData = GenXmlFunctions.GetGenXml(rpData);

            objInfo.ItemID = Update(objInfo);

            if (string.IsNullOrEmpty(GenXmlFunctions.GetField(rpData, "InvoiceRef")))
            {
                //new invoice so create unique Ref.
                var objCtrl = new EspaceController();
                GenXmlFunctions.SetField(rpData, "InvoiceRef", InvoicePrefix + objInfo.ItemID.ToString("000000") + "-" + Convert.ToString(DateTime.Now.Year).Substring(2, 2));
                objInfo.XMLData = GenXmlFunctions.GetGenXml(rpData);
                objInfo.ItemID = Update(objInfo);
            }

            return objInfo;
        }

        public void CreateInstallments(int itemId, PortalSettings portalSettings, string entityTypeCode, String ControlMapPath)
        {
            string NumPayments = null;
            string PrePaid = null;
            string TaxTotal = null;
            string SubTotal = null;
            string InvDate = null;
            string PaymentStart = null;

            var objInvInfo = Get(itemId);

            if ((objInvInfo != null))
            {
                var objTCtrl = EspaceFunctions.GetTemplateGetter();
                var rpInvData = GenXmlFunctions.InitRepeater(objInvInfo, objTCtrl.GetTemplateData(entityTypeCode + "_Detail.html", Utils.GetCurrentCulture()));

                ClearInstallmentsListFromDb(itemId);

                NumPayments = GenXmlFunctions.GetField(rpInvData, "txtNumPayments");
                PrePaid = GenXmlFunctions.GetField(rpInvData, "txtAlreadyPaid");
                TaxTotal = GenXmlFunctions.GetHiddenField(rpInvData, "dblTaxTotal");
                SubTotal = GenXmlFunctions.GetHiddenField(rpInvData, "dblSubTotal");
                InvDate = objInvInfo.GetXmlProperty("genxml/textbox/dateinvoice");
                PaymentStart = objInvInfo.GetXmlProperty("genxml/textbox/datepaymentstart");
                var invStatus = objInvInfo.GetXmlProperty("genxml/radiobuttonlist/rblstatus");
                var cID = objInvInfo.GetXmlProperty("genxml/hidden/clientid");

                if (invStatus == "STATUS2") // only create if approved
                {

                    if (!Utils.IsDate(InvDate))
                        InvDate = DateTime.Now.ToShortDateString();

                    if (!Utils.IsDate(PaymentStart))
                        PaymentStart = InvDate;

                    if (Utils.IsNumeric(NumPayments) & Utils.IsDate(PaymentStart) & Utils.IsNumeric(PrePaid, Utils.GetCurrentCulture()) & Utils.IsNumeric(SubTotal, Utils.GetCurrentCulture()) & Utils.IsNumeric(TaxTotal, Utils.GetCurrentCulture()) & !string.IsNullOrEmpty(cID))
                    {
                        if (Convert.ToInt32(NumPayments) > 0)
                        {
                            var l = CalculatePayments(Convert.ToDateTime(PaymentStart), Convert.ToDouble(SubTotal), Convert.ToDouble(TaxTotal), Convert.ToDouble(PrePaid), Convert.ToInt32(NumPayments), false);

                            foreach (EspacePayment objInfo in l)
                            {
                                var objEInfo = new NBrightInfo();
                                objEInfo.ItemID = -1;
                                objEInfo.ModifiedDate = DateTime.Now;
                                objEInfo.GUIDKey = System.Guid.NewGuid().ToString("");
                                objEInfo.TypeCode = "INSTALLMENT" + objInvInfo.ItemID.ToString("");

                                var rpGenXML = GenXmlFunctions.InitRepeater(objInvInfo, objTCtrl.GetTemplateData("INSTALLMENT_DirectPEdit.html", Utils.GetCurrentCulture()));

                                GenXmlFunctions.SetHiddenField(rpGenXML, "invoiceid", objInvInfo.ItemID.ToString(""));
                                GenXmlFunctions.SetHiddenField(rpGenXML, "clientid", GenXmlFunctions.GetField(rpInvData, "ClientID"));
                                GenXmlFunctions.SetHiddenField(rpGenXML, "invoiceref", GenXmlFunctions.GetField(rpInvData, "invoiceref"));
                                GenXmlFunctions.SetHiddenField(rpGenXML, "clientref", GenXmlFunctions.GetField(rpInvData, "txtClientRef"));
                                GenXmlFunctions.SetHiddenField(rpGenXML, "clientname", GenXmlFunctions.GetField(rpInvData, "txtClientName"));
                                GenXmlFunctions.SetHiddenField(rpGenXML, "companyname", GenXmlFunctions.GetField(rpInvData, "txtCompanyName"));
                                GenXmlFunctions.SetHiddenField(rpGenXML, "directpayment", GenXmlFunctions.GetField(rpInvData, "chkDirectPayments"));
                                GenXmlFunctions.SetHiddenField(rpGenXML, "num", objInfo.PaymentNum.ToString(""));
                                GenXmlFunctions.SetHiddenField(rpGenXML, "dtedate", objInfo.DateDue.ToString(""));
                                GenXmlFunctions.SetHiddenField(rpGenXML, "dblht", objInfo.HT.ToString(""));
                                GenXmlFunctions.SetHiddenField(rpGenXML, "dbltax", objInfo.Tax.ToString(""));
                                GenXmlFunctions.SetHiddenField(rpGenXML, "dblpaid", objInfo.PrePaid.ToString(""));
                                GenXmlFunctions.SetHiddenField(rpGenXML, "dbldue", objInfo.Due.ToString(""));
                                GenXmlFunctions.SetHiddenField(rpGenXML, "dbltotaldue", objInfo.Due.ToString(""));
                                GenXmlFunctions.SetField(rpGenXML, "chkdirectpay", "False");
                                GenXmlFunctions.SetField(rpGenXML, "chkdirectpay", "False");
                                GenXmlFunctions.SetHiddenField(rpGenXML, "transferpayment", GenXmlFunctions.GetField(rpInvData, "chkTransfer"));

                                objEInfo.XMLData = GenXmlFunctions.GetGenXml(rpGenXML);

                                var updatedItemID = Update(objEInfo);
                                objEInfo.ItemID = updatedItemID;
                                objEInfo.SetXmlProperty("genxml/hidden/itemid", updatedItemID.ToString(""));
                                Update(objEInfo);
                            }
                        }
                    }
                }
            }

        }

        public void ClearInstallmentsListFromDb(int InvItemID)
        {
            var l = GetList(-1, -1, "INSTALLMENT" + InvItemID.ToString(""));
            foreach (NBrightInfo obj in l)
            {
                var l2 = GetList(-1,-1,"INDIRECTP%", " and ([XMLData].value('(genxml/hidden/installmentid)[1]', 'nvarchar(20)') = " + obj.ItemID.ToString("") + ") ");
                foreach (NBrightInfo obj2 in l2)
                {
                    UnAllocatePayment(obj2.ItemID);
                }
                Delete(obj.ItemID);
            }
        }

        public List<EspacePayment> CalculatePayments(System.DateTime FirstPayDate, double TotalHT, double TotalTax, double PrePaid = 0, int NumPayments = 12, bool RemovePrePaid = true)
        {
            var l = new List<EspacePayment> {};
            for (int lp = 1; lp <= NumPayments; lp++)
            {
                var objInfo = new EspacePayment();
                objInfo.PaymentNum = lp;
                objInfo.DateDue = FirstPayDate.Date.AddMonths(lp - 1);
                objInfo.HT = Math.Round(TotalHT/NumPayments, 2);
                objInfo.Tax = Math.Round(TotalTax/NumPayments, 2);
                objInfo.Due = Math.Round(objInfo.HT + objInfo.Tax, 2);
                l.Add(objInfo);
            }

            //change first payment to pickup diff in rounding
            l[0].HT += Math.Round(TotalHT - (Math.Round(TotalHT/NumPayments, 2)*NumPayments), 2);
            l[0].Tax += Math.Round(TotalTax - (Math.Round(TotalTax/NumPayments, 2)*NumPayments), 2);
            l[0].Due = Math.Round((l[0].HT + l[0].Tax), 2);

            //remove any prepaid amount from payments
            if (RemovePrePaid)
            {
                //DON'T REMOVE PREPAID ON INSTALLMENTS, SO IT CAN BE ALLOCATED MANUALLY AS A PAYMENT.
                if (PrePaid > 0)
                {
                    foreach (var objInfo in l)
                    {
                        if (PrePaid > 0)
                        {
                            if (PrePaid >= objInfo.Due)
                            {
                                objInfo.PrePaid = Math.Round(objInfo.Due, 2);
                                objInfo.Due = 0;
                                PrePaid = Math.Round(PrePaid - objInfo.PrePaid, 2);
                            }
                            else
                            {
                                objInfo.PrePaid = Math.Round(PrePaid, 2);
                                objInfo.Due = Math.Round(objInfo.Due - PrePaid, 2);
                                PrePaid = 0;
                            }
                        }
                        else
                        {
                            break;
                        }
                    }
                }
            }
            return l;
        }

        public void ArchiveInstallments(int InvItemID)
        {

            var l = GetList(-1, -1, "INSTALLMENT" + InvItemID.ToString(""));

            foreach (var obj in l)
            {
                //archive by setting totaldue to 0
                obj.SetXmlProperty("genxml/hidden/dbltotaldue", "0", TypeCode.Double);
                Update(obj);
            }
        }

        public void UnArchiveInstallments(int InvItemID)
        {
            var objCtrl = new EspaceController();
            double amtDue = 0;
            double amtToPay = 0;
            double amtActualPay = 0;

            var l = objCtrl.GetList(-1,-1,"INSTALLMENT" + InvItemID.ToString(""));

            foreach (var obj in l)
            {
                amtActualPay = 0;
                var l2 = objCtrl.GetList(-1,-1,"ALLOCINDIRECTP" + obj.ItemID.ToString(""));
                foreach (var obj2 in l2)
                {
                    amtActualPay += Math.Round(Convert.ToDouble(obj2.GetXmlProperty("genxml/hidden/dblallocated")), 2);
                }
                //unarchive by setting totaldue back to correct amount
                amtToPay = Math.Round(Convert.ToDouble(obj.GetXmlProperty("genxml/hidden/dbldue")), 2);
                amtDue = amtToPay - amtActualPay;
                if (amtDue < 0)
                {
                    amtDue = 0;
                }
                obj.SetXmlProperty("genxml/hidden/dbltotaldue", amtDue.ToString(""), TypeCode.Double);
                objCtrl.Update(obj);
            }
        }

        public void CreateInvPdf(int ItemID, PortalSettings PortalSettings,String ControlMapPath)
        {
            var objIinfo = Get(ItemID);
            if (objIinfo != null)
            {

                var objSettings = GetByTypeCode("SETTINGS");

                //Update PDF Path
                objIinfo.XMLData = GenXmlFunctions.SetHiddenField(objIinfo.XMLData, "InvoicePrintPDF", PortalSettings.HomeDirectory + "InvoicesPDF/" + GenXmlFunctions.GetHiddenField(objIinfo.XMLData, "InvoiceRef") + ".pdf");
                objIinfo.XMLData = GenXmlFunctions.SetHiddenField(objIinfo.XMLData, "InvoicePDF", PortalSettings.HomeDirectory + "InvoicesPDF/" + GenXmlFunctions.GetHiddenField(objIinfo.XMLData, "InvoiceRef") + "_logo.pdf");
                objIinfo.XMLData = GenXmlFunctions.SetHiddenField(objIinfo.XMLData, "LogoImage", PortalSettings.HomeDirectoryMapPath + objSettings.GetXmlProperty("genxml/textbox/txtlogofilename"));

                // update the XML data with the changes
                Update(objIinfo);

                var clientID = GenXmlFunctions.GetHiddenField(objIinfo.XMLData, "ClientID");
                if (Utils.IsNumeric(clientID))
                {
                    var objCInfo = Get(Convert.ToInt32(clientID));
                    if ((objCInfo != null))
                    {
                        var lang = GenXmlFunctions.GetGenXmlValue(objCInfo.XMLData, "genxml/dropdownlist/ddlclientlang");
                        if (string.IsNullOrEmpty(lang))
                        {
                            lang = "fr-FR";
                        }

                        var folderPath = string.Format("{0}\\{1}\\", PortalSettings.HomeDirectoryMapPath.TrimEnd('\\'), "InvoicesPDF");
                        if (!Directory.Exists(folderPath))
                        {
                            Directory.CreateDirectory(folderPath);
                        }

                        var objTCtrl = EspaceFunctions.GetTemplateGetter();

                        var numPayments = GenXmlFunctions.GetGenXmlValue("txtNumPayments", "textbox", objIinfo.XMLData);
                        var prePaid = GenXmlFunctions.GetGenXmlValue("txtAlreadyPaid", "textbox", objIinfo.XMLData);
                        var taxTotal = GenXmlFunctions.GetHiddenField(objIinfo.XMLData, "dblTaxTotal");
                        var subTotal = GenXmlFunctions.GetHiddenField(objIinfo.XMLData, "dblSubTotal");
                        var invDate = GenXmlFunctions.GetGenXmlValue("dateInvoice", "textbox", objIinfo.XMLData);
                        var paymentStart = GenXmlFunctions.GetGenXmlValue("datePaymentStart", "textbox", objIinfo.XMLData);
                        var invStatus = GenXmlFunctions.GetGenXmlValue("rblStatus", "radiobuttonlist", objIinfo.XMLData);

                        if (!Utils.IsDate(paymentStart))
                            paymentStart = invDate;

                        //build xml data
                        var xmlData = "<root>";

                        xmlData += "<settings>";
                        xmlData += objSettings.XMLData;
                        xmlData += "</settings>";

                        xmlData += "<details>";
                        xmlData += objIinfo.XMLData;
                        xmlData += "</details>";

                        xmlData += "<articles>";
                        var l = GetList(-1,-1,"INVOICES" + ItemID.ToString(""));
                        foreach (var dItem in l)
                        {
                            xmlData += dItem.XMLData;
                        }
                        xmlData += "</articles>";

                        if (Utils.IsNumeric(numPayments) & Utils.IsDate(paymentStart) & Utils.IsNumeric(prePaid) & Utils.IsNumeric(subTotal) & Utils.IsNumeric(taxTotal))
                        {
                            if (Convert.ToInt32(numPayments) > 1)
                            {
                                var aryList = CalculatePayments(Convert.ToDateTime(paymentStart), Convert.ToDouble(subTotal), Convert.ToDouble(taxTotal), Convert.ToDouble(prePaid), Convert.ToInt32(numPayments));
                                xmlData += "<payments>";
                                foreach (var objInfo in aryList)
                                {
                                    xmlData += "<r>";
                                    xmlData += "<num>" + objInfo.PaymentNum.ToString("") + "</num>";
                                    xmlData += "<date>" + objInfo.DateDue + "</date>";
                                    xmlData += "<ht>" + objInfo.HT.ToString("0.00") + "</ht>";
                                    xmlData += "<tax>" + objInfo.Tax.ToString("0.00") + "</tax>";
                                    xmlData += "<paid>" + objInfo.PrePaid.ToString("0.00") + "</paid>";
                                    xmlData += "<due>" + objInfo.Due.ToString("0.00") + "</due>";
                                    xmlData += "</r>";
                                }
                                xmlData += "</payments>";
                            }
                        }

                        xmlData += "</root>";

                        //Product  PDF's
                        if (invStatus == "STATUS2")  //only create pdf if approved
                        {
                            var xslFile = objTCtrl.GetTemplateData("InvoiceTemplate.xsl", lang);
                            var pdfFile = PortalSettings.HomeDirectoryMapPath + "InvoicesPDF\\" + GenXmlFunctions.GetHiddenField(objIinfo.XMLData, "InvoiceRef") + ".pdf";
                            CreatePdf(xmlData, xslFile, pdfFile);
                            pdfFile = PortalSettings.HomeDirectoryMapPath + "InvoicesPDF\\" + GenXmlFunctions.GetHiddenField(objIinfo.XMLData, "InvoiceRef") + "_logo.pdf";
                            xslFile = objTCtrl.GetTemplateData("InvoiceLogoTemplate.xsl", lang);
                            CreatePdf(xmlData, xslFile, pdfFile);
                        }
                    }
                }
            }
        }

        public void CreateHostingInvoices(DateTime RunDate, String ControlMapPath)
        {
            double daysBefore = 30;

            var objSettings = GetByTypeCode("SETTINGS");

            objSettings.SetXmlProperty("genxml/hidden/invoicereport", "START: Create Invoices for Hosting. " + DateTime.Now.ToString("") + "<br/>");
            Update(objSettings);

            var strTemp = objSettings.GetXmlProperty("genxml/textbox/txtinvoicehostingbefore");
            if (Utils.IsNumeric(strTemp))
            {
                daysBefore = Convert.ToDouble(strTemp);
            }

            var l = GetList(-1,-1,"WEBSITE");

            foreach (var objInfo in l)
            {
                var renewDate = objInfo.GetXmlProperty("genxml/textbox/daterenewal");
                var offline = objInfo.GetXmlProperty("genxml/checkbox/chkclosed");
                if (offline.ToLower() != "true")
                {
                    if (Utils.IsDate(renewDate))
                    {
                        if (Convert.ToDateTime(renewDate) < RunDate.AddDays(daysBefore))
                        {
                            if (objInfo.GetXmlProperty("genxml/textbox/ddlpaytype") != "1")
                            {
                                objSettings = GetByTypeCode("SETTINGS");
                                InvoiceHosting(objSettings, objInfo, RunDate, ControlMapPath);
                            }
                        }
                    }
                    else
                    {
                        objSettings.AppendToXmlProperty("genxml/hidden/invoicereport", "WARNING: " + objInfo.GetXmlProperty("genxml/hidden/websiteref") + " : Invalid Renewal date.<br/>");
                        Update(objSettings);
                    }
                }
                else
                {
                    objSettings.AppendToXmlProperty("genxml/hidden/invoicereport", "INFO: " + objInfo.GetXmlProperty("genxml/hidden/websiteref") + "  " + objInfo.GetXmlProperty("genxml/hidden/txtprimaryurl") + " : Is checked as offline, no invoice created.<br/>");
                    Update(objSettings);
                }
            }

            objSettings = GetByTypeCode("SETTINGS");
            objSettings.AppendToXmlProperty("genxml/hidden/invoicereport", "END: Create Invoices for Hosting. " + DateTime.Now.ToString("") + "<br/>");
            Update(objSettings);
        }

        public void CreateDomainInvoices(DateTime RunDate, String ControlMapPath)
        {
            double daysBefore = 30;

            var objSettings = GetByTypeCode("SETTINGS");

            objSettings.SetXmlProperty("genxml/hidden/domainreport", "START: Create Invoices for Domains. " + DateTime.Now.ToString("") + "<br/>");
            Update(objSettings);

            var strTemp = objSettings.GetXmlProperty("genxml/textbox/txtinvoicehostingbefore");
            if (Utils.IsNumeric(strTemp))
            {
                daysBefore = Convert.ToDouble(strTemp);
            }

            var l = GetList(-1,-1,"URL");

            foreach (var objInfo in l)
            {
                var renewDate = objInfo.GetXmlProperty("genxml/textbox/dateclientrenew ");
                if (Utils.IsDate(renewDate))
                {
                    if (Convert.ToDateTime(renewDate) < RunDate.AddDays(daysBefore))
                    {
                            objSettings = GetByTypeCode("SETTINGS");
                            DomainHosting(objSettings, objInfo, RunDate, ControlMapPath);
                    }
                }
            }

            objSettings = GetByTypeCode("SETTINGS");
            objSettings.AppendToXmlProperty("genxml/hidden/domainreport", "END: Create Invoices for Domains. " + DateTime.Now.ToString("") + "<br/>");
            Update(objSettings);
        }

        public void InvoiceHosting(NBrightInfo objSettings, NBrightInfo objWebsiteInfo, DateTime RunDate, String ControlMapPath)
        {
            var adminEmail = objSettings.GetXmlProperty("genxml/textbox/txtadminemail");
            var tMode = objSettings.GetXmlProperty("genxml/checkbox/chktestmode");
            bool debugMode = tMode == "True";

            //get Website Data
            var websiteRef = objWebsiteInfo.GetXmlProperty("genxml/hidden/websiteref");
            var websiteCost = objWebsiteInfo.GetXmlProperty("genxml/textbox/txtcost");
            var supportCost = objWebsiteInfo.GetXmlProperty("genxml/textbox/txtsupportcost");
            var hostingCost = objWebsiteInfo.GetXmlProperty("genxml/textbox/txthostingcost");
            var websiteRenew = objWebsiteInfo.GetXmlProperty("genxml/textbox/daterenewal");
            if (!Utils.IsDate(websiteRenew))
            {
                objSettings.AppendToXmlProperty("genxml/hidden/invoicereport", "WARNING: " + websiteRef + " : Invalid Renewal Date.<br/>");
                Update(objSettings);
                return;
            }
            var websiteUrl = objWebsiteInfo.GetXmlProperty("genxml/hidden/txtprimaryurl");
            if (websiteUrl == "")
            {//try getting old format.
                websiteUrl = objWebsiteInfo.GetXmlProperty("genxml/textbox/txtprimaryurl");                
            }
            if (websiteUrl == "")
            {//Log Warning
                objSettings.AppendToXmlProperty("genxml/hidden/invoicereport", "WARNING: " + websiteRef + " : No primary Url.<br/>");
            }

            //get Settings Data
            var homeDirectoryMapPath = objSettings.GetXmlProperty("genxml/hidden/homedirectorymappath");
            if (homeDirectoryMapPath == "")
            {//Log ERROR
                objSettings.AppendToXmlProperty("genxml/hidden/invoicereport", "ERROR: No Portal HomeDirectoryMapPath in Settings.<br/>");
                Update(objSettings);
                return;
            }

            //get Client Data
            NBrightInfo objClient;
            var clientid = objWebsiteInfo.GetXmlProperty("genxml/hidden/clientid");
            if (Utils.IsNumeric(clientid))
            {
                objClient = Get(Convert.ToInt32(clientid));                
            }
            else
            {
                objSettings.AppendToXmlProperty("genxml/hidden/invoicereport", "ERROR: " + websiteRef + " : Invalid ClientId.<br/>");
                Update(objSettings);
                return;                
            }

            if (objClient == null)
            {
                objSettings.AppendToXmlProperty("genxml/hidden/invoicereport", "ERROR: " + websiteRef + " : ClientId '" + clientid + "' Does not exists.<br/>");
                Update(objSettings);
                return;                                
            }
            var clientref = objClient.GetXmlProperty("genxml/textbox/txtclientref");
            var clientLang = objClient.GetXmlProperty("genxml/dropdownlist/ddlclientlang/@selectedtext");
            if (clientLang == "")
            {//Log Warning
                objSettings.AppendToXmlProperty("genxml/hidden/invoicereport", "WARNING: " + websiteRef + " - " + clientref + " : No client Lnaguage.<br/>");
                clientLang = Utils.GetCurrentCulture();
            }

            var objInvoice = new NBrightInfo();
            var objTCtrl = EspaceFunctions.GetTemplateGetter();
            var templateData = objTCtrl.GetTemplateData("INVOICES_Detail.html", clientLang);
            templateData = objTCtrl.ReplaceResourceString(templateData); 
            var rpInv = GenXmlFunctions.InitRepeater(objInvoice, templateData);
            var rpArt = new Repeater();

            //update invoice before articles so that we get an id to use for the articles
            var invoiceId = -1;
            if (!debugMode)
            {                
                objInvoice = UpdateInvoice(-1, rpInv, rpArt, "INVOICES", "HS3");
                invoiceId = objInvoice.ItemID;
            }

            //create Hosting Article.
            var strText = objTCtrl.GetTemplateData("hostinginvoice.html", clientLang);
            if (string.IsNullOrEmpty(strText))
            {
                strText = "HOSTING:";
                objSettings.AppendToXmlProperty("genxml/hidden/invoicereport", "WARNING: No 'hostinginvoice.html' template found.<br/>");                
            }
            strText = strText.Replace("{websiteurl}", websiteUrl);
            var strSupportText = objTCtrl.GetTemplateData("invoicesupportarticle.html", clientLang);
            var strHostingText = objTCtrl.GetTemplateData("invoicehostingarticle.html", clientLang);
            strSupportText = strSupportText.Replace("{websiteurl}", websiteUrl);
            strHostingText = strHostingText.Replace("{websiteurl}", websiteUrl);
            
            var strUrlText = objTCtrl.GetTemplateData("urlinvoice.html", clientLang);
            if (string.IsNullOrEmpty(strUrlText))
            {
                strUrlText = "DOMAIN:";
                objSettings.AppendToXmlProperty("genxml/hidden/invoicereport", "WARNING: No 'urlinvoice.html' template found.<br/>");
            }

            double hostCost = 0;
            double totalsupportCost = 0;
            double totalhostingCost = 0;
            if (Utils.IsNumeric(supportCost)) totalsupportCost = (Convert.ToDouble(supportCost)*12);
            if (Utils.IsNumeric(hostingCost)) totalhostingCost = (Convert.ToDouble(hostingCost)*12);
            if (Utils.IsNumeric(websiteCost))
            {
                hostCost = Convert.ToDouble(websiteCost) * 12;
            }
            else
            {
                objSettings.AppendToXmlProperty("genxml/hidden/invoicereport", "ERROR: " + websiteRef + " : Invalid Hosting Cost Amount.<br/>");
                Update(objSettings);
                return;                                                
            }

            if (!debugMode)
            {
                if (totalhostingCost > 0 &&  totalsupportCost > 0)
                {
                    AddInvoiceArticle(invoiceId, clientLang, homeDirectoryMapPath, strHostingText, totalhostingCost.ToString("0.00"), ControlMapPath);
                    AddInvoiceArticle(invoiceId, clientLang, homeDirectoryMapPath, strSupportText, totalsupportCost.ToString("0.00"), ControlMapPath);
                }
                else
                {
                    AddInvoiceArticle(invoiceId, clientLang, homeDirectoryMapPath, strText, hostCost.ToString("0.00"), ControlMapPath);                    
                }
            }
            //create all urls as articles

            var l = GetList(-1,-1,"WEBURLXREF" + objWebsiteInfo.ItemID.ToString(""));

            foreach (NBrightInfo objXref in l)
            {
                var domainId = objXref.GetXmlProperty("root/xref");
                if (Utils.IsNumeric(domainId))
                {
                    var objDomain = Get(Convert.ToInt32(domainId));
                    if (objDomain != null)
                    {
                        var domainRenew = objDomain.GetXmlProperty("genxml/textbox/dateclientrenew");
                        if (!Utils.IsDate(domainRenew))
                        {
                            objSettings.AppendToXmlProperty("genxml/hidden/invoicereport", "WARNING: " + websiteRef + " - " + clientref + " Invalid Domain renew Date. Website Renewal date Used.<br/>");
                            domainRenew = websiteRenew;
                        }
                        var clientRenewDate = Convert.ToDateTime(domainRenew);
                        var defaultUrl = objDomain.GetXmlProperty("genxml/checkbox/chkisdefaulturl");
                        if ((clientRenewDate == Convert.ToDateTime(websiteRenew)))
                        {
                            var strCost = objDomain.GetXmlProperty("genxml/textbox/txtprice");
                            double domainCost = 0;
                            if (Utils.IsNumeric(strCost))
                            {
                                domainCost = Convert.ToDouble(strCost);
                            }
                            else
                            {
                                objSettings.AppendToXmlProperty("genxml/hidden/invoicereport", "WARNING: " + websiteRef + " : Invalid Domain Cost.<br/>");
                            }

                            if (!debugMode)
                            {
                                AddInvoiceArticle(invoiceId, clientLang, homeDirectoryMapPath, strUrlText + " : " + objDomain.GetXmlProperty("genxml/textbox/txturl"), domainCost.ToString("0.00"),ControlMapPath);
                                objDomain.SetXmlProperty("genxml/textbox/dateclientrenew", Utils.FormatToSave(clientRenewDate.AddYears(1).ToString(""), TypeCode.DateTime), TypeCode.DateTime);
                                Update(objDomain);
                            }
                        }
                    }
                }
            }

            //update the invoice with client details 
            if (!debugMode)
            {
                UpdateInvoiceXML(invoiceId, Convert.ToInt32(clientid), Convert.ToDateTime(websiteRenew), "12", RunDate);
                objWebsiteInfo.SetXmlProperty("genxml/textbox/daterenewal", Utils.FormatToSave(Convert.ToDateTime(websiteRenew).AddYears(1).ToString(""), TypeCode.DateTime), TypeCode.DateTime);
                Update(objWebsiteInfo);
            }
            //update hosting website renewal date
            objSettings.AppendToXmlProperty("genxml/hidden/invoicereport", "INVOICE: website: " + websiteRef + ". client: " + clientref + ". Created.<br/>");
            Update(objSettings);

        }

        public void DomainHosting(NBrightInfo objSettings, NBrightInfo objDomainInfo, DateTime RunDate, String ControlMapPath)
        {
            var tMode = objSettings.GetXmlProperty("genxml/checkbox/chktestmode");
            bool debugMode = tMode == "True";

            //get Website Data
            var domainUrl = objDomainInfo.GetXmlProperty("genxml/textbox/txturl");
            var domainCost = objDomainInfo.GetXmlProperty("genxml/textbox/txtprice");
            var domainRenew = objDomainInfo.GetXmlProperty("genxml/textbox/dateclientrenew");
            if (!Utils.IsDate(domainRenew))
            {
                objSettings.AppendToXmlProperty("genxml/hidden/domainreport", "WARNING: " + domainUrl + " : Invalid Renewal Date.<br/>");
                Update(objSettings);
                return;
            }

            //get Settings Data
            var homeDirectoryMapPath = objSettings.GetXmlProperty("genxml/hidden/homedirectorymappath");
            if (homeDirectoryMapPath == "")
            {
                //Log ERROR
                objSettings.AppendToXmlProperty("genxml/hidden/domainreport", "ERROR: No Portal HomeDirectoryMapPath in Settings.<br/>");
                Update(objSettings);
                return;
            }
            var adminEmail = objSettings.GetXmlProperty("genxml/textbox/txtadminemail");

            //get Client Data
            NBrightInfo objClient;
            var clientid = objDomainInfo.GetXmlProperty("genxml/hidden/clientid");
            if (Utils.IsNumeric(clientid))
            {
                objClient = Get(Convert.ToInt32(clientid));
            }
            else
            {
                objSettings.AppendToXmlProperty("genxml/hidden/domainreport", "ERROR: " + domainUrl + " : Invalid ClientId.<br/>");
                Update(objSettings);
                return;
            }

            if (objClient == null)
            {
                objSettings.AppendToXmlProperty("genxml/hidden/domainreport", "ERROR: " + domainUrl + " : ClientId '" + clientid + "' Does not exists.<br/>");
                Update(objSettings);
                return;
            }
            var clientref = objClient.GetXmlProperty("genxml/textbox/txtclientref");
            var clientLang = objClient.GetXmlProperty("genxml/dropdownlist/ddlclientlang/@selectedtext");
            if (clientLang == "")
            {
                //Log Warning
                objSettings.AppendToXmlProperty("genxml/hidden/domainreport", "WARNING: " + domainUrl + " - " + clientref + " : No client Lnaguage.<br/>");
                clientLang = Utils.GetCurrentCulture();
            }

            var objInvoice = new NBrightInfo();
            var objTCtrl = EspaceFunctions.GetTemplateGetter();
            var templateData = objTCtrl.GetTemplateData("INVOICES_Detail.html", clientLang);
            templateData = objTCtrl.ReplaceResourceString(templateData); 
            var rpInv = GenXmlFunctions.InitRepeater(objInvoice, templateData);
            var rpArt = new Repeater();

            //update invoice before articles so that we get an id to use for the articles
            var invoiceId = -1;
            if (!debugMode)
            {
                objInvoice = UpdateInvoice(-1, rpInv, rpArt, "INVOICES", "UL3");
                invoiceId = objInvoice.ItemID;
            }
            //create Hosting Article.
            var strUrlText = objTCtrl.GetTemplateData("urlinvoice.html", clientLang);
            if (string.IsNullOrEmpty(strUrlText))
            {
                strUrlText = "DOMAIN:";
                objSettings.AppendToXmlProperty("genxml/hidden/domainreport", "WARNING: No 'urlinvoice.html' template found.<br/>");
            }

            double dCost = 0;
            if (Utils.IsNumeric(domainCost))
            {
                dCost = Convert.ToDouble(domainCost);
            }
            else
            {
                objSettings.AppendToXmlProperty("genxml/hidden/domainreport", "ERROR: " + domainUrl + " : Invalid Cost Amount.<br/>");
                Update(objSettings);
                return;
            }

            if (!debugMode)
            {
                AddInvoiceArticle(invoiceId, clientLang, homeDirectoryMapPath, strUrlText + " : " + domainUrl, dCost.ToString("0.00"),ControlMapPath);
                //update the invoice with client details 
                UpdateInvoiceXML(invoiceId, Convert.ToInt32(clientid), Convert.ToDateTime(domainRenew), "1", RunDate);
                objDomainInfo.SetXmlProperty("genxml/textbox/dateclientrenew", Utils.FormatToSave(Convert.ToDateTime(domainRenew).AddYears(1).ToString(""), TypeCode.DateTime), TypeCode.DateTime);
                Update(objDomainInfo);
            }

            //update hosting website renewal date
            objSettings.AppendToXmlProperty("genxml/hidden/domainreport", "INVOICE: domain: " + domainUrl + ". client: " + clientref + ". Created.<br/>");
            Update(objSettings);

        }

        public void AddInvoiceArticle(int InvoiceId, string clientLang, string homeDirectoryMapPath, string Summary, string Amount, String ControlMapPath)
        {
            var objInfo = new NBrightInfo { ItemID = -1, TypeCode = "INVOICES" + InvoiceId.ToString(""), ModifiedDate = DateTime.Now };
            var articleId = Update(objInfo);
            objInfo = Get(articleId);

            var objTCtrl = EspaceFunctions.GetTemplateGetter();
            var templateData = objTCtrl.GetTemplateData("ARTICLES_Detail.html", clientLang);
            templateData = objTCtrl.ReplaceResourceString(templateData);
            var rpArt = GenXmlFunctions.InitRepeater(objInfo, templateData);

            objInfo.XMLData = GenXmlFunctions.GetGenXml(rpArt);
            objInfo.SetXmlProperty("genxml/textbox/txtsummary", Summary);
            objInfo.SetXmlProperty("genxml/textbox/txtprice", Amount, TypeCode.Double);

            Update(objInfo);
        }

        private int UpdateInvoiceXML(int invoiceID, int clientID, System.DateTime paymentStartDate, string NumOfPayments, DateTime RunDate)
        {
            //update invoice xml
            var objInvInfo =  Get(invoiceID);
            var objClientInfo = Get(clientID);

            if ((objClientInfo != null) & (objInvInfo != null))
            {
                objInvInfo.SetXmlProperty("genxml/hidden/clientid", clientID.ToString(""));
                objInvInfo.SetXmlProperty("genxml/hidden/txtclientref", objClientInfo.GetXmlProperty("genxml/textbox/txtclientref"));
                objInvInfo.SetXmlProperty("genxml/hidden/clientref", objClientInfo.GetXmlProperty("genxml/textbox/txtclientref"));
                objInvInfo.SetXmlProperty("genxml/textbox/txtclientname", objClientInfo.GetXmlProperty("genxml/textbox/txtclientname"));
                objInvInfo.SetXmlProperty("genxml/textbox/txtcompanyname", objClientInfo.GetXmlProperty("genxml/textbox/txtcompanyname"));
                objInvInfo.SetXmlProperty("genxml/textbox/txtclientadd1", objClientInfo.GetXmlProperty("genxml/textbox/txtclientadd1"));
                objInvInfo.SetXmlProperty("genxml/textbox/txtclientadd2", objClientInfo.GetXmlProperty("genxml/textbox/txtclientadd2"));
                objInvInfo.SetXmlProperty("genxml/textbox/txtclientpc", objClientInfo.GetXmlProperty("genxml/textbox/txtclientpc"));
                objInvInfo.SetXmlProperty("genxml/textbox/txtclientadd3", objClientInfo.GetXmlProperty("genxml/textbox/txtclientadd3"));
            }

            if (objInvInfo != null)
            {
                objInvInfo.SetXmlProperty("genxml/textbox/dateinvoice", Utils.FormatToSave(RunDate.ToString(""), TypeCode.DateTime), TypeCode.DateTime);
                objInvInfo.SetXmlProperty("genxml/textbox/datepaymentstart", Utils.FormatToSave(paymentStartDate.ToString(""), TypeCode.DateTime), TypeCode.DateTime);
                objInvInfo.SetXmlProperty("genxml/textbox/txtnumpayments", NumOfPayments);
            }

            return Update(objInvInfo);

        }

        #endregion

        #region "Client Emails"

        public void SendClientEmailReport()
        {
            var objSettings = GetByTypeCode("SETTINGS");

            objSettings.SetXmlProperty("genxml/hidden/clientreport", "START: Client Email Report. " + DateTime.Now.ToString("") + "<br/>");
            Update(objSettings);

            var homeDirectoryMapPath = objSettings.GetXmlProperty("genxml/hidden/homedirectorymappath");
            if (homeDirectoryMapPath == "")
            {
                //Log ERROR
                objSettings.AppendToXmlProperty("genxml/hidden/clientreport", "ERROR: No Portal HomeDirectoryMapPath in Settings.<br/>");
                Update(objSettings);
                return;
            }
            var controlMapPath = objSettings.GetXmlProperty("genxml/hidden/controlmappath");
            if (controlMapPath == "")
            {
                //Log ERROR
                objSettings.AppendToXmlProperty("genxml/hidden/clientreport", "ERROR: No controlMapPath in Settings.<br/>");
                Update(objSettings);
                return;
            }

            var fromEmail = objSettings.GetXmlProperty("genxml/textbox/txtfromemail");
            var adminEmail = objSettings.GetXmlProperty("genxml/textbox/txtadminemail");
            var testEmail = objSettings.GetXmlProperty("genxml/textbox/txttestemail");
            var tMode = objSettings.GetXmlProperty("genxml/checkbox/chktestmode");
            bool debugMode = tMode == "True";
            if (debugMode)
            {
                adminEmail = testEmail;
            }

            var errCount = 0;
            var okCount = 0;
            var strFilter = "";
            // Line here for testing -----------
            //strFilter = " and Itemid = '349'";
            //---------------------------------
            var l = GetList(-1,-1,"CLIENT",strFilter);
            foreach (var objClient in l)
            {

                try
                {

                    if (objClient.GetXmlProperty("genxml/checkbox/chkenableemail").ToLower() == "true")
                    {
                        var clientref = objClient.GetXmlProperty("genxml/textbox/txtclientref");
                        var clientLang = objClient.GetXmlProperty("genxml/dropdownlist/ddlclientlang/@selectedtext");
                        if (clientLang == "")
                        {
                            //Log Warning
                            objSettings.AppendToXmlProperty("genxml/hidden/clientreport", "WARNING: " + clientref + " : No client Lnaguage.<br/>");
                            clientLang = Utils.GetCurrentCulture();
                        }
                        var clientEmail = objClient.GetXmlProperty("genxml/textbox/txtpersonalemail");
                        if (clientEmail != "")
                        {
                            if (debugMode)
                            {
                                clientEmail = testEmail;
                            }

                            var objTCtrl = EspaceFunctions.GetTemplateGetter();
                            var strSubjectText = objTCtrl.GetTemplateData("clientreportsubject.html", clientLang);
                            if (string.IsNullOrEmpty(strSubjectText))
                            {
                                strSubjectText = "Report";
                                objSettings.AppendToXmlProperty("genxml/hidden/clientreport", "WARNING: No 'clientreportsubject.html' template found.<br/>");
                            }

                            var strEmail = GetClientReport(objClient.ItemID,clientLang);

                            if (strEmail.StartsWith("ERROR"))
                            {
                                objSettings.AppendToXmlProperty("genxml/hidden/clientreport", strEmail);
                                Update(objSettings);
                                return;                                
                            }

                            if (debugMode)
                            {
                                if (okCount < 10)
                                {
                                    DotNetNuke.Services.Mail.Mail.SendMail(fromEmail, clientEmail, "", strSubjectText, strEmail, "", "HTML", "", "", "", "");                                    
                                }
                            }
                            else
                            {
                                DotNetNuke.Services.Mail.Mail.SendMail(fromEmail, clientEmail, "", strSubjectText, strEmail, "", "HTML", "", "", "", "");                                
                            }
                            okCount += 1;                                
                        }
                    }
                }
                catch (Exception e)
                {
                    errCount += 1;
                    if (errCount <= 3)
                    {
                        objSettings.AppendToXmlProperty("genxml/hidden/clientreport", "<hr/>ItemID: " + objClient.ItemID.ToString("") + "  " + e.Message + "<hr/><br/>");                        
                    }
                }
            }
            objSettings.AppendToXmlProperty("genxml/hidden/clientreport", "Client Email Reports Sent : " + okCount.ToString("") + "<br/>");
            objSettings.AppendToXmlProperty("genxml/hidden/clientreport", "Client Email Reports Failed : " + errCount.ToString("") + "<br/>");
            objSettings.AppendToXmlProperty("genxml/hidden/clientreport", "END:  Client Email Report. " + DateTime.Now.ToString("") + "<br/>");
            Update(objSettings);
        }

        public string GetClientReport(int ClientItemId, string reportLang)
        {
            var objSettings = GetByTypeCode("SETTINGS");
            var homeDirectoryMapPath = objSettings.GetXmlProperty("genxml/hidden/homedirectorymappath");
            var controlMapPath = objSettings.GetXmlProperty("genxml/hidden/controlmappath");

            var objTCtrl = EspaceFunctions.GetTemplateGetter();

            var xslReport = objTCtrl.GetTemplateData("clientreport.xsl", reportLang);
            if (string.IsNullOrEmpty(xslReport))
            {
                return "ERROR: No 'clientreport.xsl' template found.<br/>";
            }

            var xmlReport = GetClientXML(ClientItemId,true);

            var strEmail = XslUtils.XslTransInMemory(xmlReport, xslReport);

            return strEmail;
        }

        public string GetClientXML(int ClientItemId, bool withSettings = false)
        {
            var strXML = "<root>";
            XmlDataDocument xmlDoc = default(XmlDataDocument);

            if (withSettings)
            {
                var objSettings = GetByTypeCode("SETTINGS");
                strXML += "<settings>";
                strXML += objSettings.XMLData;
                strXML += "</settings>";
            }

            var obj = Get(ClientItemId);

            if ((obj != null))
            {
                strXML += "<client>";
                strXML += "<item>";
                var strClientXML = "";
                try
                {
                    var xmlClientDoc = new XmlDataDocument();
                    xmlClientDoc.LoadXml(obj.XMLData);
                    XmlNode t = xmlClientDoc.SelectSingleNode("genxml/textbox/auditlog");
                    if (t != null) if (t.ParentNode != null) t.ParentNode.RemoveChild(t);
                    strClientXML = xmlClientDoc.OuterXml;
                }
                catch (Exception)
                {
                    strClientXML = "XML FORMAT ERROR";
                }

                strXML += "<xmldata>" + strClientXML + "</xmldata>";
                strXML += "</item>";
                strXML += "</client>";

                strXML += "<project>";
                var strFilter = " and ([xmlData].value('(genxml/hidden/clientid)[1]', 'nvarchar(10)') = '" + ClientItemId.ToString("") + "') ";
                strFilter += " and ([xmlData].value('(genxml/radiobuttonlist/rblstatus)[1]', 'nvarchar(10)') != '20') ";
                var l = GetList(-1,-1,"PROJECT", strFilter);
                foreach (var objL in l)
                {
                    strXML += "<item>";
                    strXML += "<xmldata>" + objL.XMLData + "</xmldata>";
                    strXML += "</item>";
                }
                strXML += "</project>";


                strXML += "<website>";
                strFilter = " and ([xmlData].value('(genxml/hidden/clientid)[1]', 'nvarchar(10)') = '" + ClientItemId.ToString("") + "') ";
                strFilter += " and ([xmlData].value('(genxml/checkbox/chkclosed)[1]', 'nvarchar(10)') != 'True') ";
                l = GetList(-1,-1,"WEBSITE", strFilter);
                foreach (var objL in l)
                {
                    strXML += "<item>";
                    strXML += "<xmldata>" + objL.XMLData + "</xmldata>";
                    strXML += "</item>";
                }
                strXML += "</website>";

                strXML += "<urls>";
                strFilter = " and ([xmlData].value('(genxml/hidden/clientid)[1]', 'nvarchar(10)') = '" + ClientItemId.ToString("") + "') ";
                l = GetList(-1,-1,"URL", strFilter);
                foreach (var objL in l)
                {
                    strXML += "<item>";
                    strXML += "<xmldata>" + objL.XMLData + "</xmldata>";
                    strXML += "<urlsemail>";
                    l = GetList(-1,-1,"URLEMAIL" + objL.ItemID.ToString(""));
                    foreach (var objL2 in l)
                    {
                        strXML += "<item>";
                        strXML += "<xmldata>" + objL2.XMLData + "</xmldata>";
                        strXML += "</item>";
                    }
                    strXML += "</urlsemail>";
                    strXML += "</item>";
                }
                strXML += "</urls>";

                strXML += "<outstanding>";

                strFilter = " and ([xmlData].value('(genxml/hidden/clientid)[1]', 'nvarchar(10)') = '" + ClientItemId.ToString("") + "')  and (convert(decimal(18,2),isnull(([xmlData].value('(genxml/hidden/dbltotaldue)[1]', 'money')),0)) > 0) ";
                //strFilter = " and ([xmlData].value('(genxml/hidden/clientid)[1]', 'nvarchar(10)') = '" + ClientItemId.ToString("") + "')  and (convert(decimal(18,2),isnull(nullif(([xmlData].value('(genxml/hidden/dbltotaldue)[1]', 'money'),'')),0)) > 0) ";
                l = GetList(-1, -1, "INSTALLMENT%", strFilter);
                decimal outTotal = 0;
                foreach (var objL in l)
                {
                    strXML += "<item>";
                    strXML += "<xmldata>" + objL.XMLData + "</xmldata>";
                    strXML += "</item>";
                    var tot = GenXmlFunctions.GetGenXmlValue(objL.XMLData, "genxml/hidden/dbltotaldue");
                    if (Utils.IsNumeric(tot))
                    {
                        outTotal += Convert.ToDecimal(tot);
                    }
                }
                strXML += "<total>" + outTotal.ToString("") + "</total>";

                strXML += "</outstanding>";
            }

            strXML += "</root>";
            return strXML;
        }

        #endregion

        #region "Payment aollocation"

        public void UnAllocatePayment(int AllocatedPayID)
        {
            var objEInfo = Get(AllocatedPayID);

            if ((objEInfo != null))
            {
                //update the dblactualpaid field in the installment
                var strTempXML = objEInfo.GetXmlProperty("genxml/hidden/installmentid");
                if (Utils.IsNumeric(strTempXML))
                {
                    var installmentID = Convert.ToInt32(strTempXML);
                    var objIInfo = Get(installmentID);

                    if ((objIInfo != null))
                    {
                        string AlocAmt = null;
                        double dblAlocAmt = 0;
                        double Amount = 0;
                        double dblTotalDue = 0;
                        double dblInsDue = 0;

                        strTempXML = objEInfo.GetXmlProperty("genxml/hidden/dblallocated");
                        if (Utils.IsNumeric(strTempXML))
                        {
                            Amount = Math.Round(Convert.ToDouble(strTempXML), 2);
                        }
                        else
                        {
                            Amount = 0;
                        }

                        AlocAmt = objIInfo.GetXmlProperty("genxml/hidden/dblactualpaid");
                        if (Utils.IsNumeric(AlocAmt))
                        {
                            dblAlocAmt = Math.Round(Convert.ToDouble(AlocAmt), 2) - Amount;
                        }
                        else
                        {
                            dblAlocAmt = 0;
                        }

                        strTempXML = objIInfo.GetXmlProperty("genxml/hidden/dbldue");
                        if (Utils.IsNumeric(strTempXML))
                        {
                            dblInsDue = Math.Round(Convert.ToDouble(strTempXML), 2);
                        }
                        else
                        {
                            dblInsDue = 0;
                        }

                        dblTotalDue = dblInsDue - dblAlocAmt;

                        objIInfo.SetXmlProperty("genxml/hidden/dblactualpaid", dblAlocAmt.ToString("0.00"), TypeCode.Double);
                        objIInfo.SetXmlProperty("genxml/hidden/dbltotaldue", dblTotalDue.ToString("0.00"), TypeCode.Double);

                        Update(objIInfo);
                    }
                }

                //mark the allocated pay as deleted
                Delete(AllocatedPayID);

                //update payment allocated amount
                strTempXML = objEInfo.GetXmlProperty("genxml/hidden/paymentid");
                if (Utils.IsNumeric(strTempXML))
                {
                    var paymentID = Convert.ToInt32(strTempXML);
                    var objIInfo = Get(paymentID);
                    if ((objIInfo != null))
                    {
                        var dblAAmt = GetAlreadyAllocatedPay(paymentID.ToString(""));
                        objIInfo.SetXmlProperty("genxml/hidden/dblallocatedamt", dblAAmt.ToString("0.00"), TypeCode.Double);
                        Update(objIInfo);
                    }
                }

            }

        }

        public double GetAlreadyAllocatedPay(string PaymentItemId)
        {
            double totalAllocated = 0;
            var l = GetList(-1,-1,"INDIRECTP" + PaymentItemId);

            foreach (var obj in l)
            {
                totalAllocated += Math.Round(Convert.ToDouble(obj.GetXmlProperty("genxml/hidden/dblallocated")), 2);
            }
            return Math.Round(totalAllocated, 2);
        }

        public int AllocatePayment(PortalSettings PortalSettings, int InDirectPayID, int InstallmentID, double Amount, string ModulePath,String ControlMapPath)
        {
            int rtnItemID = -1;

            var objIInfo = Get(InstallmentID);

            if ((objIInfo != null))
            {
                var objEInfo = new NBrightInfo();
                objEInfo.ItemID = -1;
                objEInfo.ModifiedDate = DateTime.Now;
                objEInfo.GUIDKey = System.Guid.NewGuid().ToString("");
                objEInfo.TypeCode = "INDIRECTP" + InDirectPayID.ToString("");

                var objTCtrl = EspaceFunctions.GetTemplateGetter();
                var strTempl = objTCtrl.GetTemplateData("INDIRECTP_Allocated.html", Utils.GetCurrentCulture());

                var rpData = GenXmlFunctions.InitRepeater(objEInfo, strTempl);

                GenXmlFunctions.SetHiddenField(rpData, "paymentid", InDirectPayID.ToString(""));
                GenXmlFunctions.SetHiddenField(rpData, "installmentid", InstallmentID.ToString(""));
                GenXmlFunctions.SetHiddenField(rpData, "invoiceref", objIInfo.GetXmlProperty("genxml/hidden/invoiceref"));
                GenXmlFunctions.SetHiddenField(rpData, "dtedate", objIInfo.GetXmlProperty("genxml/hidden/dtedate"));
                GenXmlFunctions.SetHiddenField(rpData, "dbldue", objIInfo.GetXmlProperty("genxml/hidden/dbldue"));

                //update the dblactualpaid field in the installment
                string alocAmt = null;
                string insAmt = null;
                double dblAlocAmt = 0;
                double dblTotalDue = 0;
                double dblInsDue = 0;
                alocAmt = objIInfo.GetXmlProperty("genxml/hidden/dblactualpaid");
                if (Utils.IsNumeric(alocAmt))
                {
                    dblAlocAmt = Math.Round(Convert.ToDouble(alocAmt), 2) + Amount;
                }
                else
                {
                    dblAlocAmt = Amount;
                }
                dblAlocAmt = Math.Round(Convert.ToDouble(dblAlocAmt), 2);
                insAmt = objIInfo.GetXmlProperty("genxml/hidden/dbldue");
                if (Utils.IsNumeric(insAmt))
                {
                    dblInsDue = Math.Round(Convert.ToDouble(insAmt), 2);
                }
                else
                {
                    dblInsDue = 0;
                }


                //check if the payment amount is not too much, if it is recalulate it.
                if (dblAlocAmt > dblInsDue)
                {
                    dblAlocAmt = dblInsDue - dblAlocAmt;
                    Amount = dblAlocAmt;
                }

                dblTotalDue = dblInsDue - dblAlocAmt;

                objIInfo.SetXmlProperty("genxml/hidden/dblactualpaid", dblAlocAmt.ToString(""), TypeCode.Double);
                objIInfo.SetXmlProperty("genxml/hidden/dbltotaldue", dblTotalDue.ToString(""), TypeCode.Double);

                if (Amount > 0)
                {
                    Update(objIInfo);

                    GenXmlFunctions.SetHiddenField(rpData, "dblallocated", Amount.ToString(""));
                    objEInfo.XMLData = GenXmlFunctions.GetGenXml(rpData);
                    rtnItemID = Update(objEInfo);
                }

            }

            return rtnItemID;

        }

        #endregion

        #region "Estimate Public Methods"

        public NBrightInfo UpdateEstimate(int itemId, Repeater rpData, Repeater rpArticle, string entityTypeCode, PortalSettings PortalSettings)
        {
            // Do any special updates that are required.
            double grandTotal = 0;
            double subTotal = 0;
            double taxTotal = 0;
            double totalDue = 0;
            string alreadyPaid = null;

            //rebuild all articles.
            taxTotal = 0;
            subTotal = 0;

            foreach (RepeaterItem dItem in rpArticle.Items)
            {
                //calculate total
                var articlePrice = GenXmlFunctions.GetField(rpArticle, "txtPrice", dItem.ItemIndex);
                var articleTax = GenXmlFunctions.GetField(rpArticle, "ddlTax", dItem.ItemIndex);
                double articleTotal = 0;
                if (Utils.IsNumeric(articlePrice, Utils.GetCurrentCulture()) & Utils.IsNumeric(articleTax, Utils.GetCurrentCulture()))
                {
                    subTotal += Convert.ToDouble(articlePrice);
                    articleTotal = Math.Round(Convert.ToDouble(articlePrice)*((100 + Convert.ToDouble(articleTax))/100), 2);
                    taxTotal += Convert.ToDouble(articleTotal) - Convert.ToDouble(articlePrice);
                }
                else
                {
                    articleTotal = 0;
                }
                grandTotal += articleTotal;
                GenXmlFunctions.SetHiddenField(rpArticle, "dblTotalPrice", Convert.ToString(articleTotal), dItem.ItemIndex);

                var objAInfo = new NBrightInfo();
                if (Utils.IsNumeric(GenXmlFunctions.GetHiddenField(rpArticle, "ItemID", dItem.ItemIndex)))
                {
                    objAInfo.ItemID = GenXmlFunctions.GetFieldAsInteger(rpArticle, "ItemID", dItem.ItemIndex);
                }
                else
                {
                    objAInfo.ItemID = -1;
                }
                objAInfo.TypeCode = entityTypeCode + Convert.ToString(itemId);
                objAInfo.XMLData = GenXmlFunctions.GetGenXml(rpArticle, dItem.ItemIndex);
                Update(objAInfo);
            }


            alreadyPaid = GenXmlFunctions.GetField(rpData, "txtAlreadyPaid");
            if (Utils.IsNumeric(alreadyPaid, Utils.GetCurrentCulture()))
            {
                totalDue = grandTotal - Math.Round(Convert.ToDouble(alreadyPaid), 2);
            }
            else
            {
                totalDue = grandTotal;
            }

            GenXmlFunctions.SetHiddenField(rpData, "dteModifiedDate", Convert.ToString(DateTime.Now));
            GenXmlFunctions.SetHiddenField(rpData, "dblGrandTotal", Convert.ToString(grandTotal));
            GenXmlFunctions.SetHiddenField(rpData, "dblSubTotal", Convert.ToString(subTotal));
            GenXmlFunctions.SetHiddenField(rpData, "dblTaxTotal", Convert.ToString(taxTotal));
            GenXmlFunctions.SetHiddenField(rpData, "dblTotalDue", Convert.ToString(totalDue));

            var objInfo = Get(itemId); // get working data
            if (objInfo == null)
            {
                // new item, so create it
                objInfo = new NBrightInfo();
                objInfo.ItemID = itemId;
                objInfo.TypeCode = entityTypeCode;
            }

            objInfo.XMLData = GenXmlFunctions.GetGenXml(rpData);

            objInfo.ItemID = Update(objInfo);

            if (string.IsNullOrEmpty(GenXmlFunctions.GetField(rpData, "EstimateRef")))
            {
                //new invoice so create unique Ref.
                var objCtrl = new EspaceController();
                GenXmlFunctions.SetField(rpData, "EstimateRef", "DE3" + objInfo.ItemID.ToString("000000") + "-" + Convert.ToString(DateTime.Now.Year).Substring(2, 2));
                objInfo.XMLData = GenXmlFunctions.GetGenXml(rpData);
                objInfo.ItemID = Update(objInfo);
            }

            return objInfo;
        }


        public void CreateEstimatePdf(int itemId, PortalSettings portalSettings, String ControlMapPath)
        {
            var objIinfo = Get(itemId);
            if (objIinfo != null)
            {
                var objSettings = GetByTypeCode("SETTINGS");

                //Update PDF Path
                objIinfo.XMLData = GenXmlFunctions.SetHiddenField(objIinfo.XMLData, "EstimatePrintPDF", portalSettings.HomeDirectory + "EstimatesPDF/" + GenXmlFunctions.GetHiddenField(objIinfo.XMLData, "EstimateRef") + ".pdf");
                objIinfo.XMLData = GenXmlFunctions.SetHiddenField(objIinfo.XMLData, "EstimatePrintPDFrtn", portalSettings.HomeDirectory + "EstimatesPDF/" + GenXmlFunctions.GetHiddenField(objIinfo.XMLData, "EstimateRef") + "_return.pdf");
                objIinfo.XMLData = GenXmlFunctions.SetHiddenField(objIinfo.XMLData, "EstimatePDF", portalSettings.HomeDirectory + "EstimatesPDF/" + GenXmlFunctions.GetHiddenField(objIinfo.XMLData, "EstimateRef") + "_logo.pdf");
                objIinfo.XMLData = GenXmlFunctions.SetHiddenField(objIinfo.XMLData, "LogoImage", portalSettings.HomeDirectoryMapPath + objSettings.GetXmlProperty("genxml/textbox/txtlogofilename"));

                // update the XML data with the changes
                Update(objIinfo);

                var clientId = GenXmlFunctions.GetHiddenField(objIinfo.XMLData, "ClientID");
                if (Utils.IsNumeric(clientId))
                {
                    var objCInfo = Get(Convert.ToInt32(clientId));
                    if ((objCInfo != null))
                    {
                        var lang = GenXmlFunctions.GetGenXmlValue(objCInfo.XMLData, "genxml/dropdownlist/ddlclientlang");
                        if (string.IsNullOrEmpty(lang))
                        {
                            lang = "fr-FR";
                        }

                        var folderPath = string.Format("{0}\\{1}\\", portalSettings.HomeDirectoryMapPath.TrimEnd('\\'), "EstimatesPDF");
                        if (!Directory.Exists(folderPath))
                        {
                            Directory.CreateDirectory(folderPath);
                        }

                        var objTCtrl = EspaceFunctions.GetTemplateGetter();

                        var numPayments = GenXmlFunctions.GetGenXmlValue("txtNumPayments", "textbox", objIinfo.XMLData);
                        var prePaid = GenXmlFunctions.GetGenXmlValue("txtAlreadyPaid", "textbox", objIinfo.XMLData);
                        var taxTotal = GenXmlFunctions.GetHiddenField(objIinfo.XMLData, "dblTaxTotal");
                        var subTotal = GenXmlFunctions.GetHiddenField(objIinfo.XMLData, "dblSubTotal");
                        var invDate = GenXmlFunctions.GetGenXmlValue("dateInvoice", "textbox", objIinfo.XMLData);
                        var paymentStart = GenXmlFunctions.GetGenXmlValue("datePaymentStart", "textbox", objIinfo.XMLData);

                        if (!Utils.IsDate(paymentStart))
                            paymentStart = invDate;

                        //build xml data
                        var xmlData = "<root>";

                        xmlData += "<settings>";
                        xmlData += objSettings.XMLData;
                        xmlData += "</settings>";

                        xmlData += "<details>";
                        xmlData += objIinfo.XMLData;
                        xmlData += "</details>";

                        xmlData += "<articles>";
                        var l = GetList(-1,-1,"ESTIMATES" + itemId.ToString(""));
                        foreach (var dItem in l)
                        {
                            xmlData += dItem.XMLData;
                        }
                        xmlData += "</articles>";


                        xmlData += "</root>";

                        //Estimate  PDF's
                        var xslFile = objTCtrl.GetTemplateData("EstimateTemplate.xsl", lang);
                        var pdfFile = portalSettings.HomeDirectoryMapPath + "EstimatesPDF\\" + GenXmlFunctions.GetHiddenField(objIinfo.XMLData, "EstimateRef") + ".pdf";
                        CreatePdf(xmlData, xslFile, pdfFile);
                        pdfFile = portalSettings.HomeDirectoryMapPath + "EstimatesPDF\\" + GenXmlFunctions.GetHiddenField(objIinfo.XMLData, "EstimateRef") + "_return.pdf";
                        xslFile = objTCtrl.GetTemplateData("EstimateTemplate2.xsl", lang);
                        CreatePdf(xmlData, xslFile, pdfFile);
                        pdfFile = portalSettings.HomeDirectoryMapPath + "EstimatesPDF\\" + GenXmlFunctions.GetHiddenField(objIinfo.XMLData, "EstimateRef") + "_logo.pdf";
                        xslFile = objTCtrl.GetTemplateData("EstimateLogoTemplate.xsl", lang);
                        CreatePdf(xmlData, xslFile, pdfFile);

                    }
                }
            }
        }

        #endregion

        #region "Url Method"

        public string SetWebsiteDefaultUrl(int websteXrefId)
        {
            //get websiteid
            var objXref = Get(websteXrefId);
            if (objXref != null)
            {
                var websiteId = GenXmlFunctions.GetGenXmlValue(objXref.XMLData, "root/parentid");
                var newDefaultId = GenXmlFunctions.GetGenXmlValue(objXref.XMLData, "root/xref");
                if (Utils.IsNumeric(newDefaultId))
                {
                    var objList = GetList(-1,-1,"WEBURLXREF" + websiteId);
                    foreach (var obj in objList)
                    {
                        var linkedXref = GenXmlFunctions.GetGenXmlValue(obj.XMLData, "root/linkedxref");
                        if (Utils.IsNumeric(linkedXref))
                        {
                            var objInfo = Get(Convert.ToInt32(linkedXref));
                            if (objInfo != null)
                            {
                                var urlId = GenXmlFunctions.GetGenXmlValue(objInfo.XMLData, "root/parentid");
                                if (Utils.IsNumeric(urlId))
                                {
                                    var objInfo2 = Get(Convert.ToInt32(urlId));
                                    if (objInfo2 != null)
                                    {
                                        if ((objInfo2.ItemID == Convert.ToInt32(newDefaultId)))
                                        {
                                            objInfo2.XMLData = GenXmlFunctions.SetGenXmlValue(objInfo2.XMLData, "genxml/checkbox/chkisdefaulturl", "True");
                                        }
                                        else
                                        {
                                            objInfo2.XMLData = GenXmlFunctions.SetGenXmlValue(objInfo2.XMLData, "genxml/checkbox/chkisdefaulturl", "False");
                                        }
                                        Update(objInfo2);
                                    }
                                }
                            }
                        }

                    }
                }
                return websiteId;
            }
            return "";
        }


        public string GetWebsiteDefaultUrl(int websiteId)
        {
            //get websiteid
                    var objList = GetList(-1,-1,"WEBURLXREF" + websiteId);
                    foreach (var obj in objList)
                    {
                        var linkedXref = GenXmlFunctions.GetGenXmlValue(obj.XMLData, "root/linkedxref");
                        if (Utils.IsNumeric(linkedXref))
                        {
                            var objInfo = Get(Convert.ToInt32(linkedXref));
                            if (objInfo != null)
                            {
                                var urlId = GenXmlFunctions.GetGenXmlValue(objInfo.XMLData, "root/parentid");
                                if (Utils.IsNumeric(urlId))
                                {
                                    var objInfo2 = Get(Convert.ToInt32(urlId));
                                    if (objInfo2 != null)
                                    {
                                       if (GenXmlFunctions.GetGenXmlValue(objInfo2.XMLData, "genxml/checkbox/chkisdefaulturl") == "True")
                                       {
                                           return GenXmlFunctions.GetGenXmlValue(objInfo2.XMLData, "genxml/textbox/txturl");
                                       }
                                    }
                                }
                            }
                        }

                    }
            return "";
        }

        #endregion

        #region "General"

        public void ClearArticleListFromDb(int InvItemID, string EntityTypeCode)
        {
            var l = GetList(-1,-1,EntityTypeCode + InvItemID.ToString(""));
            foreach (NBrightInfo obj in l)
            {
                Delete(obj.ItemID);
            }
        }

        public void CreatePdf(string xmlData, string xslFileData, string OutputFilePath)
        {
            var pdfiz = new Pdfizer.HtmlToPdfConverter();
            Stream ostream = new FileStream(OutputFilePath, FileMode.Create, FileAccess.ReadWrite, FileShare.None);
            var html = XslUtils.XslTransInMemory(xmlData, xslFileData);

            pdfiz.Open(ostream);
            pdfiz.Run(html);
            pdfiz.Close();

        }

        public IDataReader ExecuteSql(string SqlCommand)
        {
            return DataProvider.Instance().ExecuteSql(SqlCommand);
        }


        #endregion

        #region "Setttings"

        public NBrightInfo GetByTypeCode(string TypeCode)
        {
            var objL = GetList(-1,-1,TypeCode, "", "", 1);
            if (objL.Count >= 1)
            {
                return objL[0];
            }
            return null;
        }

        #endregion

        #region "Project Costs"

        public string GetCostsRep(int projectItemId, string reportLang, int selMonth, int selYear)
        {
            var objSettings = GetByTypeCode("SETTINGS");
            var homeDirectoryMapPath = objSettings.GetXmlProperty("genxml/hidden/homedirectorymappath");
            var controlMapPath = objSettings.GetXmlProperty("genxml/hidden/controlmappath");

            var objTCtrl = EspaceFunctions.GetTemplateGetter();

            var rpTempl = objTCtrl.GetTemplateData("costmonthreport.html", reportLang);
            if (string.IsNullOrEmpty(rpTempl))
            {
                return "ERROR: No 'costmonthreport.html' template found.<br/>";
            }

            var l = GetCostData(projectItemId, selMonth, selYear);
            var strOut = "<table class='datatable' border='0' cellpadding='0' cellspacing='0'><tr><th></th><th>Date</th><th>Costs</th><th>Log</th></tr>";
            strOut += GenXmlFunctions.RenderRepeater(l, rpTempl);
            strOut += "</table>";
            return strOut;
        }

        public List<NBrightInfo> GetCostData(int projectItemId, int selMonth, int selYear)
        {
            var obj = Get(projectItemId);
            var l = new List<NBrightInfo>();
            if ((obj != null))
            {

                var strFilter = " and ([xmlData].value('(genxml/hidden/projectid)[1]', 'nvarchar(10)') = '" + projectItemId.ToString("") + "') ";
                if (selMonth != -1 && selYear != -1)
                {
                    strFilter += " and ([xmlData].value('(genxml/textbox/txtdate)[1]', 'nchar(7)') = '" + selYear.ToString("0000") + "-" + selMonth.ToString("00") + "') ";
                }
                else if (selMonth == -1 && selYear != -1)
                {
                    strFilter += " and ([xmlData].value('(genxml/textbox/txtdate)[1]', 'nchar(4)') = '" + selYear.ToString("0000") + "') ";
                }

                const string strOrderBy = " order by [xmlData].value('(genxml/textbox/txtdate)[1]', 'nvarchar(10)') DESC";

                l = GetList(-1, -1, "PROJCOST", strFilter, strOrderBy);

            }

            return l;
        }

        public void RecalcProjectCost(int projectItemId)
        {

            var obj = Get(projectItemId);

            if ((obj != null))
            {

                double recalctime = 0;

                var strFilter = " and ([xmlData].value('(genxml/hidden/projectid)[1]', 'nvarchar(10)') = '" + projectItemId.ToString("") + "') ";

                var l = GetList(-1, -1, "PROJCOST", strFilter);
                foreach (var objL in l)
                {
                    var strTime = objL.GetXmlPropertyDouble("genxml/textbox/txtcosts");
                    recalctime += strTime;
                }

                obj.SetXmlProperty("genxml/hidden/hidallocatedcosts", String.Format("{0:0.00}", recalctime));

                Update(obj);

            }
        }


        #endregion

        #region "Project Time"

        public string GetTimeRep(int projectItemId, string reportLang,int selMonth,int selYear,string emp)
        {
            var objSettings = GetByTypeCode("SETTINGS");
            var homeDirectoryMapPath = objSettings.GetXmlProperty("genxml/hidden/homedirectorymappath");
            var controlMapPath = objSettings.GetXmlProperty("genxml/hidden/controlmappath");

            var objTCtrl = EspaceFunctions.GetTemplateGetter();

            var xslReport = objTCtrl.GetTemplateData("timemonthreport.xsl", reportLang);
            if (string.IsNullOrEmpty(xslReport))
            {
                return "ERROR: No 'timemonthreport.xsl' template found.<br/>";
            }

            var xmlReport = GetTimeXml(projectItemId, selMonth, selYear, emp);

            var strTimeRep = XslUtils.XslTransInMemory(xmlReport, xslReport);

            return strTimeRep;
        }

        public string GetGroupTimeRep(int projectItemId, string reportLang, int selMonth, int selYear)
        {
            var objSettings = GetByTypeCode("SETTINGS");
            var homeDirectoryMapPath = objSettings.GetXmlProperty("genxml/hidden/homedirectorymappath");
            var controlMapPath = objSettings.GetXmlProperty("genxml/hidden/controlmappath");

            var objTCtrl = EspaceFunctions.GetTemplateGetter();

            var xslReport = objTCtrl.GetTemplateData("timegroupreport.xsl", reportLang);
            if (string.IsNullOrEmpty(xslReport))
            {
                return "ERROR: No 'timegroupreport.xsl' template found.<br/>";
            }

            var xmlReport = GetGroupTimeXml(projectItemId, selMonth, selYear);

            var strTimeRep = XslUtils.XslTransInMemory(xmlReport, xslReport);

            return strTimeRep;
        }

        public string GetTimeXml(int projectItemId, int selMonth, int selYear,string emp)
        {
            var strXml = "<root>";
            XmlDataDocument xmlDoc = default(XmlDataDocument);

            var obj = Get(projectItemId);

            if ((obj != null))
            {

                var strFilter = " and ([xmlData].value('(genxml/hidden/projectid)[1]', 'nvarchar(10)') = '" + projectItemId.ToString("") + "') ";
                if (selMonth != -1 && selYear != -1)
                {
                    strFilter += " and ([xmlData].value('(genxml/textbox/txtdate)[1]', 'nchar(7)') = '" + selYear.ToString("0000") + "-" + selMonth.ToString("00") + "') ";                    
                }
                else if (selMonth == -1 && selYear != -1)
                {
                    strFilter += " and ([xmlData].value('(genxml/textbox/txtdate)[1]', 'nchar(4)') = '" + selYear.ToString("0000") + "') ";
                }

                if (emp != "")
                {
                    strFilter += " and ([xmlData].value('(genxml/textbox/txtemployee)[1]', 'nvarchar(50)') = '" + emp + "') ";                    
                }

                const string strOrderBy = " order by [xmlData].value('(genxml/textbox/txtdate)[1]', 'nvarchar(10)') DESC";

                var l = GetList(-1, -1, "PROJTIME", strFilter,strOrderBy);

                strXml += "<project>";
                strXml += "<item>" + obj.XMLData + "</item>";
                strXml += "<time>";

                foreach (var objL in l)
                {
                    strXml += "<item id='" + objL.ItemID.ToString(CultureInfo.InvariantCulture) + "'>";
                    strXml += objL.XMLData;
                    strXml += "</item>";
                }

                strXml += "</time>";
                strXml += "</project>";

            }

            strXml += "</root>";
            return strXml;
        }

        public string GetGroupTimeXml(int projectItemId, int selMonth, int selYear)
        {
            var strXml = "<root>";
            XmlDataDocument xmlDoc = default(XmlDataDocument);

            var obj = Get(projectItemId);

            if ((obj != null))
            {

                var strFilter = " and ([xmlData].value('(genxml/hidden/projectid)[1]', 'nvarchar(10)') = '" + projectItemId.ToString("") + "') ";
                if (selMonth != -1 && selYear != -1)
                {
                    strFilter += " and ([xmlData].value('(genxml/textbox/txtdate)[1]', 'nchar(7)') = '" + selYear.ToString("0000") + "-" + selMonth.ToString("00") + "') ";
                }
                else if (selMonth == -1 && selYear != -1)
                {
                    strFilter += " and ([xmlData].value('(genxml/textbox/txtdate)[1]', 'nchar(4)') = '" + selYear.ToString("0000") + "') ";
                }

                const string strOrderBy = " order by [xmlData].value('(genxml/textbox/txtemployee)[1]', 'nvarchar(10)') ";

                var l = GetList(-1, -1, "PROJTIME", strFilter, strOrderBy);

                var empList = new Dictionary<String, Double>();

                foreach (var objL in l)
                {
                    var emp = objL.GetXmlProperty("genxml/textbox/txtemployee");
                    var strHrs = objL.GetXmlProperty("genxml/textbox/txthours");
                    var strEmpXml = 0;
                    if (Utils.IsNumeric(strHrs))
                    {
                        if (empList.ContainsKey(emp))
                        {
                            empList[emp] = empList[emp] + Convert.ToDouble(strHrs);
                        }
                        else
                        {
                            empList.Add(emp, Convert.ToDouble(strHrs));
                        }                        
                    }
                }

                foreach (var hrs in empList )
                {
                    strXml += "<item projectid='" + projectItemId + "' emp='" + hrs.Key + "' hours='" + hrs.Value.ToString(CultureInfo.InvariantCulture) + "' />";                    
                }


            }

            strXml += "</root>";
            return strXml;
        }

        public void RecalcProjectTime(int projectItemId)
        {

            var obj = Get(projectItemId);

            if ((obj != null))
            {

                double recalctime = 0;

                var strFilter = " and ([xmlData].value('(genxml/hidden/projectid)[1]', 'nvarchar(10)') = '" + projectItemId.ToString("") + "') ";

                var l = GetList(-1, -1, "PROJTIME", strFilter);
                foreach (var objL in l)
                {
                    var strTime = objL.GetXmlPropertyDouble("genxml/textbox/txthours");
                        recalctime += strTime;
                }

                obj.SetXmlProperty("genxml/hidden/totalhours", recalctime.ToString(CultureInfo.GetCultureInfo("en-US")));

                var invAmt = obj.GetXmlProperty("genxml/textbox/txtinvamt");
                if (Utils.IsNumeric(invAmt))
                {
                    if (Convert.ToDouble(invAmt) > 0 && recalctime > 0)
                    {
                        var hourlyRate = Convert.ToDouble(invAmt) / recalctime;
                        obj.SetXmlPropertyDouble("genxml/hidden/hourlyrate", hourlyRate);
                    }
                    else
                    {
                        obj.SetXmlProperty("genxml/hidden/hourlyrate", "0");                                                
                    }
                }

                Update(obj);

            }
        }

#endregion

    }

}
